﻿#region << 文件说明 >>

/*----------------------------------------------------------------
 * 命名空间：Vampirewal.BlogCore.Controls.Form
 * 唯一标识：ef9a2ce6-da26-472e-86bd-04e2131a5223
 * 文件名：Form
 *
 * 创建者：杨程
 * 电子邮箱：235160615@qq.com
 * 创建时间：2024/6/28 16:17:02
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/

#endregion << 文件说明 >>

namespace Vampirewal.BlogCore;

/// <summary>
/// 表单容器控件
/// </summary>
public sealed class Form : ContainerControlBase
{
    /// <summary>
    /// 构造函数
    /// </summary>
    internal Form()
    {
    }

    public override List<ControlBase> Children { get; internal set; }
    public override string Id { get; set; }
    public override string Title { get; set; }

    public override string ConverToHtml()
    {
        StringBuilder sb = new StringBuilder();

        Param par = new Param();

        sb.AppendLine($"<el-form :model=\"form\"  label-width=\"auto\" {par}>");

        foreach (var item in Children)
        {
            sb.AppendLine(item.ConverToHtml());
        }

        sb.AppendLine($"</el-form>");

        if (Buttons.Count > 0)
        {
            sb.AppendLine($"<el-footer>");
            sb.AppendLine($"<span class=\"dialog-footer\">");
            foreach (var item in Buttons)
            {
                sb.AppendLine(item.ConverToHtml());
            }
            sb.AppendLine($"</span>");
            sb.AppendLine($"</el-footer>");
        }

        return sb.ToString();
    }

    /// <summary>
    /// 按钮集合
    /// </summary>
    internal List<ControlBase> Buttons { get; set; }
}

/// <summary>
/// 单个表单项控件
/// </summary>
public sealed class FormItem : ContainerControlBase
{
    public override List<ControlBase> Children { get; internal set; }
    public override string Id { get; set; }
    public override string Title { get; set; }

    public override string ConverToHtml()
    {
        StringBuilder sb = new StringBuilder();

        Param par = new Param();

        sb.AppendLine($"<el-form-item label=\"{Title}\" {par}>");

        foreach (var item in Children)
        {
            sb.AppendLine(item.ConverToHtml());
        }

        sb.AppendLine($"</el-form-item>");

        return sb.ToString();
    }
}

public static partial class App
{
    /// <summary>
    /// 创建表单
    /// </summary>
    /// <param name="children"></param>
    /// <returns></returns>
    public static Form CreateForm(Action<List<ControlBase>> children)
    {
        Form form = new Form()
        {
            Id = GenerateId(),
            Title = "表单",
            Children = new List<ControlBase>(),
            Buttons = new List<ControlBase>(),
        };

        children?.Invoke(form.Children);

        return form;
    }

    /// <summary>
    /// 通过model创建表单
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public static Form CreateForm<T>()
    {
        var type = typeof(T);

        var modelAttr = type.GetCustomAttribute<FormModelAttribute>();

        if (modelAttr == null)
            throw new Exception("该模型不是表单模型!");

        Form form = new Form()
        {
            Id = GenerateId(),
            Title = "表单",
            Children = new List<ControlBase>(),
            Buttons = new List<ControlBase>(),
        };

        if (modelAttr.HasButton)
        {
            var buttonAttrs = type.GetCustomAttributes<FormButtonAttribute>();

            foreach (var attr in buttonAttrs)
            {
                Button button = null;

                switch (attr.ButtonExcuteType)
                {
                    case ButtonExcuteType.Submit:
                        {
                            button = CreateButton(attr.Label, attr.ButtonType).SetSubmit(attr.MethodName);
                        }
                        break;

                    case ButtonExcuteType.Custom:
                        button = CreateButton(attr.Label, attr.ButtonType);
                        break;

                    case ButtonExcuteType.ClosePage:
                        break;

                    default:
                        break;
                }

                form.Buttons.Add(button);
            }
        }

        var Props = type.GetProperties();

        foreach (var item in Props)
        {
            var attrs = item.GetCustomAttributes(true).OfType<FormPropertyAttribute>().ToList();
            var jsonPropAttr = item.GetCustomAttribute<JsonPropertyNameAttribute>();

            if (attrs != null)
            {
                if (attrs.Count == 1)
                {
                    FormPropertyAttribute attr = attrs[0];
                    string modelName = jsonPropAttr != null ? jsonPropAttr.Name : item.Name;
                    if (attr is FormInputAttribute input)
                    {
                        switch (input.InputType)
                        {
                            case InputTypeEnum.Text:
                                CreateFormItem(input.Label, child => CreateInput($"form.{modelName}", input.Watermark).AddToChildren(child)).AddToChildren(form.Children);
                                break;
                            case InputTypeEnum.TextArea:
                                CreateFormItem(input.Label, child => CreateTextArea($"form.{modelName}", input.RowCount,input.Watermark).AddToChildren(child)).AddToChildren(form.Children);
                                break;
                            default:
                                break;
                        }

                        
                    }
                    else if (attr is FormNumInputAttribute numInput)
                    {
                        CreateFormItem(numInput.Label, child => CreateNumInput($"form.{modelName}", numInput.Min, numInput.Max, numInput.Precision, numInput.Step).AddToChildren(child)).AddToChildren(form.Children);
                    }
                }
                else if(attrs.Count>1)
                {
                    throw new Exception("表单特性在同一属性上只能存在1个！");
                }

            }
        }

        return form;
    }

    /// <summary>
    /// 创建表单项
    /// </summary>
    /// <param name="lable"></param>
    /// <param name="children"></param>
    /// <returns></returns>
    public static FormItem CreateFormItem(string lable, Action<List<ControlBase>> children)
    {
        FormItem item = new FormItem()
        {
            Id = GenerateId(),
            Title = lable,
            Children = new List<ControlBase>()
        };

        children?.Invoke(item.Children);

        return item;
    }
}